<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>class Fiber - RDoc Documentation</title>


<script src="./js/navigation.js" defer></script>
<script src="./js/search.js" defer></script>
<script src="./js/search_index.js" defer></script>
<script src="./js/searcher.js" defer></script>
<script src="./js/darkfish.js" defer></script>

<script src="./js/jquery-3.2.0.min.js"></script>

<script src="./js/vue.min.js"></script>
<script src="./js/js.cookie.min.js"></script>

<link href="./css/fonts.css" rel="stylesheet">
<link id='rdoccss' href="./css/rdoc.css" rel="stylesheet">
<link href="./css/carbon17.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "./";
  var index_rel_prefix = "./";
  var darkModeCsseHref = "./css/rdoc-dm.css"
  var defaultModeCssHref = "./css/rdoc.css"
  // var cssDarkmode = Cookies.get('darkmode');
  
  if( Cookies.get("darkmode") == "true") {
	$('#rdoccss').attr("href", darkModeCsseHref);
}

//  https://cssdeck.com/blog/simple-jquery-stylesheet-switcher/

document.write('<style type="text/css">body{display:none}</style>');

</script>


</head>
<body id="top" role="document" class="class">
  <!-- this is class.html -->

  <div id='actionbar' >
    <div class='wrapper mdiv'>
      <ul class='grids g0'></ul>
    </div> 
    <!-- VERSION HEADER for 3.3.0-preview2 NOT FOUND -->
  </div> <!-- end action bar -->

  <div class='wrapper hdiv'>

    


    <nav id='vapp' role="navigation">
    <div id="project-navigation">
      <div id="home-section" role="region" title="Quick navigation" class="nav-section">
  <h2><a href="./index.html" rel="home">Home</a></h2>

  <div id="table-of-contents-navigation"  >
    <a href="./table_of_contents.html#pages">Pages</a>
    <a href="./table_of_contents.html#classes">Classes</a>
    <a href="./table_of_contents.html#methods">Methods</a>
  </div>
</div>

      <div id="search-section" role="search" class="project-section initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <div id="search-field-wrapper">
      <input id="search-field" role="combobox" aria-label="Search"
             aria-autocomplete="list" aria-controls="search-results"
             type="text" name="search" placeholder="Search" spellcheck="false"
             title="Type to search, Up and Down to navigate, Enter to load">
    </div>

    <ul id="search-results" aria-label="Search Results"
        aria-busy="false" aria-expanded="false"
        aria-atomic="false" class="initially-hidden"></ul>
  </form>
</div>

    </div>


    

    <button id='toggleThing' @click="toggleNav()" >Show/hide navigation</button>
    <div :class="isOpen ? 'block' : 'hidden' " id='toggleMe'>
      <div id="class-metadata">
        
        
<div id="parent-class-section" class="nav-section">
  <h3>Parent</h3>

  <p class="link"><a href="Object.html">Object</a>
</div>

        
        
        
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
  <h3>Methods</h3>

  <ul class="link-list" role="directory">
    <li ><a href="#method-c-5B-5D">::[]</a>
    <li ><a href="#method-c-5B-5D-3D">::[]=</a>
    <li ><a href="#method-c-blocking">::blocking</a>
    <li ><a href="#method-c-blocking-3F">::blocking?</a>
    <li ><a href="#method-c-current">::current</a>
    <li ><a href="#method-c-current_scheduler">::current_scheduler</a>
    <li ><a href="#method-c-new">::new</a>
    <li ><a href="#method-c-schedule">::schedule</a>
    <li ><a href="#method-c-scheduler">::scheduler</a>
    <li ><a href="#method-c-set_scheduler">::set_scheduler</a>
    <li ><a href="#method-c-yield">::yield</a>
    <li ><a href="#method-i-alive-3F">#alive?</a>
    <li ><a href="#method-i-backtrace">#backtrace</a>
    <li ><a href="#method-i-backtrace_locations">#backtrace_locations</a>
    <li ><a href="#method-i-blocking-3F">#blocking?</a>
    <li ><a href="#method-i-inspect">#inspect</a>
    <li ><a href="#method-i-kill">#kill</a>
    <li ><a href="#method-i-raise">#raise</a>
    <li ><a href="#method-i-resume">#resume</a>
    <li ><a href="#method-i-storage">#storage</a>
    <li ><a href="#method-i-storage-3D">#storage=</a>
    <li ><a href="#method-i-to_s">#to_s</a>
    <li ><a href="#method-i-transfer">#transfer</a>
  </ul>
</div>

      </div>
     </div>
    </nav>


    <div id='extraz'><div class='adzbox-index'  >
      
     </div>         
    </div>

    <main role="main" aria-labelledby="class-Fiber">
    <h1 id="class-Fiber" class="class">
      class Fiber
    </h1>

    <section class="description">
    
<p>Fibers are primitives for implementing light weight cooperative concurrency in Ruby. Basically they are a means of creating code blocks that can be paused and resumed, much like threads. The main difference is that they are never preempted and that the scheduling must be done by the programmer and not the VM.</p>

<p>As opposed to other stackless light weight concurrency models, each fiber comes with a stack.  This enables the fiber to be paused from deeply nested function calls within the fiber block.  See the ruby(1) manpage to configure the size of the fiber stack(s).</p>

<p>When a fiber is created it will not run automatically. Rather it must be explicitly asked to run using the <a href="Fiber.html#method-i-resume"><code>Fiber#resume</code></a> method. The code running inside the fiber can give up control by calling <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a> in which case it yields control back to caller (the caller of the <a href="Fiber.html#method-i-resume"><code>Fiber#resume</code></a>).</p>

<p>Upon yielding or termination the <a href="Fiber.html"><code>Fiber</code></a> returns the value of the last executed expression</p>

<p>For instance:</p>

<pre class="ruby"><span class="ruby-identifier">fiber</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword">do</span>
  <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">yield</span> <span class="ruby-value">1</span>
  <span class="ruby-value">2</span>
<span class="ruby-keyword">end</span>

<span class="ruby-identifier">puts</span> <span class="ruby-identifier">fiber</span>.<span class="ruby-identifier">resume</span>
<span class="ruby-identifier">puts</span> <span class="ruby-identifier">fiber</span>.<span class="ruby-identifier">resume</span>
<span class="ruby-identifier">puts</span> <span class="ruby-identifier">fiber</span>.<span class="ruby-identifier">resume</span>
</pre>

<p><em>produces</em></p>

<pre>1
2
FiberError: dead fiber called</pre>

<p>The <a href="Fiber.html#method-i-resume"><code>Fiber#resume</code></a> method accepts an arbitrary number of parameters, if it is the first call to <a href="Fiber.html#method-i-resume"><code>resume</code></a> then they will be passed as block arguments. Otherwise they will be the return value of the call to <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a></p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">fiber</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">first</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">second</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">yield</span> <span class="ruby-identifier">first</span> <span class="ruby-operator">+</span> <span class="ruby-value">2</span>
<span class="ruby-keyword">end</span>

<span class="ruby-identifier">puts</span> <span class="ruby-identifier">fiber</span>.<span class="ruby-identifier">resume</span> <span class="ruby-value">10</span>
<span class="ruby-identifier">puts</span> <span class="ruby-identifier">fiber</span>.<span class="ruby-identifier">resume</span> <span class="ruby-value">1_000_000</span>
<span class="ruby-identifier">puts</span> <span class="ruby-identifier">fiber</span>.<span class="ruby-identifier">resume</span> <span class="ruby-string">&quot;The fiber will be dead before I can cause trouble&quot;</span>
</pre>

<p><em>produces</em></p>

<pre>12
1000000
FiberError: dead fiber called</pre>

<h2 id="class-Fiber-label-Non-blocking+Fibers">Non-blocking Fibers<span><a href="#class-Fiber-label-Non-blocking+Fibers">&para;</a> <a href="#top">&uarr;</a></span></h2>

<p>The concept of <em>non-blocking fiber</em> was introduced in Ruby 3.0. A non-blocking fiber, when reaching a operation that would normally block the fiber (like <code>sleep</code>, or wait for another process or I/O) will yield control to other fibers and allow the <em>scheduler</em> to handle blocking and waking up (resuming) this fiber when it can proceed.</p>

<p>For a <a href="Fiber.html"><code>Fiber</code></a> to behave as non-blocking, it need to be created in <a href="Fiber.html#method-c-new"><code>Fiber.new</code></a> with <code>blocking: false</code> (which is the default), and <a href="Fiber.html#method-c-scheduler"><code>Fiber.scheduler</code></a> should be set with <a href="Fiber.html#method-c-set_scheduler"><code>Fiber.set_scheduler</code></a>. If <a href="Fiber.html#method-c-scheduler"><code>Fiber.scheduler</code></a> is not set in the current thread, blocking and non-blocking fibers’ behavior is identical.</p>

<p>Ruby doesn’t provide a scheduler class: it is expected to be implemented by the user and correspond to <a href="Fiber/Scheduler.html"><code>Fiber::Scheduler</code></a>.</p>

<p>There is also <a href="Fiber.html#method-c-schedule"><code>Fiber.schedule</code></a> method, which is expected to immediately perform the given block in a non-blocking manner. Its actual implementation is up to the scheduler.</p>

    </section>

      <section id="5Buntitled-5D" class="documentation-section">





                <section id="public-class-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Class Methods</h3>
                </header>

                  <div id="method-c-5B-5D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          Fiber[key] &rarr; value
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns the value of the fiber storage variable identified by <code>key</code>.</p>

<p>The <code>key</code> must be a symbol, and the value is set by Fiber#[]= or Fiber#store.</p>

<p>See also <a href="Fiber.html#method-c-5B-5D-3D"><code>Fiber::[]=</code></a>.</p>

                              <div class="method-source-code" id="5B-5D-source">
            <pre>static VALUE
rb_fiber_storage_aref(VALUE class, VALUE key)
{
    Check_Type(key, T_SYMBOL);

    VALUE storage = fiber_storage_get(fiber_current(), FALSE);
    if (storage == Qnil) return Qnil;

    return rb_hash_aref(storage, key);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-5B-5D-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          Fiber[key] = value
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Assign <code>value</code> to the fiber storage variable identified by <code>key</code>. The variable is created if it doesn’t exist.</p>

<p><code>key</code> must be a <a href="Symbol.html"><code>Symbol</code></a>, otherwise a <a href="TypeError.html"><code>TypeError</code></a> is raised.</p>

<p>See also <a href="Fiber.html#method-c-5B-5D"><code>Fiber::[]</code></a>.</p>

                              <div class="method-source-code" id="5B-5D-3D-source">
            <pre>static VALUE
rb_fiber_storage_aset(VALUE class, VALUE key, VALUE value)
{
    Check_Type(key, T_SYMBOL);

    VALUE storage = fiber_storage_get(fiber_current(), value != Qnil);
    if (storage == Qnil) return Qnil;

    if (value == Qnil) {
        return rb_hash_delete(storage, key);
    }
    else {
        return rb_hash_aset(storage, key, value);
    }
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-blocking" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          blocking{|fiber| ...} &rarr; result
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Forces the fiber to be blocking for the duration of the block. Returns the result of the block.</p>

<p>See the “Non-blocking fibers” section in class docs for details.</p>

                              <div class="method-source-code" id="blocking-source">
            <pre>VALUE
rb_fiber_blocking(VALUE class)
{
    VALUE fiber_value = rb_fiber_current();
    rb_fiber_t *fiber = fiber_ptr(fiber_value);

    // If we are already blocking, this is essentially a no-op:
    if (fiber-&gt;blocking) {
        return rb_yield(fiber_value);
    }
    else {
        return rb_ensure(fiber_blocking_yield, fiber_value, fiber_blocking_ensure, fiber_value);
    }
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-blocking-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          blocking? &rarr; false or 1
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns <code>false</code> if the current fiber is non-blocking. <a href="Fiber.html"><code>Fiber</code></a> is non-blocking if it was created via passing <code>blocking: false</code> to <a href="Fiber.html#method-c-new"><code>Fiber.new</code></a>, or via <a href="Fiber.html#method-c-schedule"><code>Fiber.schedule</code></a>.</p>

<p>If the current <a href="Fiber.html"><code>Fiber</code></a> is blocking, the method returns 1. Future developments may allow for situations where larger integers could be returned.</p>

<p>Note that, even if the method returns <code>false</code>, <a href="Fiber.html"><code>Fiber</code></a> behaves differently only if <a href="Fiber.html#method-c-scheduler"><code>Fiber.scheduler</code></a> is set in the current thread.</p>

<p>See the “Non-blocking fibers” section in class docs for details.</p>

                              <div class="method-source-code" id="blocking-3F-source">
            <pre>static VALUE
rb_fiber_s_blocking_p(VALUE klass)
{
    rb_thread_t *thread = GET_THREAD();
    unsigned blocking = thread-&gt;blocking;

    if (blocking == 0)
        return Qfalse;

    return INT2NUM(blocking);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-current" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          current &rarr; fiber
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns the current fiber. If you are not running in the context of a fiber this method will return the root fiber.</p>

                              <div class="method-source-code" id="current-source">
            <pre>static VALUE
rb_fiber_s_current(VALUE klass)
{
    return rb_fiber_current();
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-current_scheduler" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          current_scheduler &rarr; obj or nil
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns the <a href="Fiber.html"><code>Fiber</code></a> scheduler, that was last set for the current thread with <a href="Fiber.html#method-c-set_scheduler"><code>Fiber.set_scheduler</code></a> if and only if the current fiber is non-blocking.</p>

                              <div class="method-source-code" id="current_scheduler-source">
            <pre>static VALUE
rb_fiber_current_scheduler(VALUE klass)
{
    return rb_fiber_scheduler_current();
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-new" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          new(blocking: false, storage: true) { |*args| ... } &rarr; fiber
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Creates new <a href="Fiber.html"><code>Fiber</code></a>. Initially, the fiber is not running and can be resumed with <a href="Fiber.html#method-i-resume"><code>resume</code></a>. Arguments to the first <a href="Fiber.html#method-i-resume"><code>resume</code></a> call will be passed to the block:</p>

<pre class="ruby"><span class="ruby-identifier">f</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">initial</span><span class="ruby-operator">|</span>
   <span class="ruby-identifier">current</span> = <span class="ruby-identifier">initial</span>
   <span class="ruby-identifier">loop</span> <span class="ruby-keyword">do</span>
     <span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;current: #{current.inspect}&quot;</span>
     <span class="ruby-identifier">current</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">yield</span>
   <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">f</span>.<span class="ruby-identifier">resume</span>(<span class="ruby-value">100</span>)     <span class="ruby-comment"># prints: current: 100</span>
<span class="ruby-identifier">f</span>.<span class="ruby-identifier">resume</span>(<span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">3</span>) <span class="ruby-comment"># prints: current: [1, 2, 3]</span>
<span class="ruby-identifier">f</span>.<span class="ruby-identifier">resume</span>          <span class="ruby-comment"># prints: current: nil</span>
<span class="ruby-comment"># ... and so on ...</span>
</pre>

<p>If <code>blocking: false</code> is passed to <code>Fiber.new</code>, <em>and</em> current thread has a <a href="Fiber.html#method-c-scheduler"><code>Fiber.scheduler</code></a> defined, the <a href="Fiber.html"><code>Fiber</code></a> becomes non-blocking (see “Non-blocking Fibers” section in class docs).</p>

<p>If the <code>storage</code> is unspecified, the default is to inherit a copy of the storage from the current fiber. This is the same as specifying <code>storage: true</code>.</p>

<pre class="ruby"><span class="ruby-constant">Fiber</span>[<span class="ruby-value">:x</span>] = <span class="ruby-value">1</span>
<span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword">do</span>
  <span class="ruby-constant">Fiber</span>[<span class="ruby-value">:x</span>] <span class="ruby-comment"># =&gt; 1</span>
  <span class="ruby-constant">Fiber</span>[<span class="ruby-value">:x</span>] = <span class="ruby-value">2</span>
<span class="ruby-keyword">end</span>.<span class="ruby-identifier">resume</span>
<span class="ruby-constant">Fiber</span>[<span class="ruby-value">:x</span>] <span class="ruby-comment"># =&gt; 1</span>
</pre>

<p>If the given <code>storage</code> is <code>nil</code>, this function will lazy initialize the internal storage, which starts as an empty hash.</p>

<pre class="ruby"><span class="ruby-constant">Fiber</span>[<span class="ruby-value">:x</span>] = <span class="ruby-string">&quot;Hello World&quot;</span>
<span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">storage:</span> <span class="ruby-keyword">nil</span>) <span class="ruby-keyword">do</span>
  <span class="ruby-constant">Fiber</span>[<span class="ruby-value">:x</span>] <span class="ruby-comment"># nil</span>
<span class="ruby-keyword">end</span>
</pre>

<p>Otherwise, the given <code>storage</code> is used as the new fiber’s storage, and it must be an instance of <a href="Hash.html"><code>Hash</code></a>.</p>

<p>Explicitly using <code>storage: true</code> is currently experimental and may change in the future.</p>

                              <div class="method-source-code" id="new-source">
            <pre>static VALUE
rb_fiber_initialize(int argc, VALUE* argv, VALUE self)
{
    return rb_fiber_initialize_kw(argc, argv, self, rb_keyword_given_p());
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-schedule" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          schedule { |*args| ... } &rarr; fiber
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>The method is <em>expected</em> to immediately run the provided block of code in a separate non-blocking fiber.</p>

<pre class="ruby"><span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Go to sleep!&quot;</span>

<span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">set_scheduler</span>(<span class="ruby-constant">MyScheduler</span>.<span class="ruby-identifier">new</span>)

<span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">schedule</span> <span class="ruby-keyword">do</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Going to sleep&quot;</span>
  <span class="ruby-identifier">sleep</span>(<span class="ruby-value">1</span>)
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;I slept well&quot;</span>
<span class="ruby-keyword">end</span>

<span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Wakey-wakey, sleepyhead&quot;</span>
</pre>

<p>Assuming MyScheduler is properly implemented, this program will produce:</p>

<pre>Go to sleep!
Going to sleep
Wakey-wakey, sleepyhead
...1 sec pause here...
I slept well</pre>

<p>…e.g. on the first blocking operation inside the <a href="Fiber.html"><code>Fiber</code></a> (<code>sleep(1)</code>), the control is yielded to the outside code (main fiber), and <em>at the end of that execution</em>, the scheduler takes care of properly resuming all the blocked fibers.</p>

<p>Note that the behavior described above is how the method is <em>expected</em> to behave, actual behavior is up to the current scheduler’s implementation of <a href="Fiber/Scheduler.html#method-i-fiber"><code>Fiber::Scheduler#fiber</code></a> method. Ruby doesn’t enforce this method to behave in any particular way.</p>

<p>If the scheduler is not set, the method raises <code>RuntimeError (No scheduler is available!)</code>.</p>

                              <div class="method-source-code" id="schedule-source">
            <pre>static VALUE
rb_fiber_s_schedule(int argc, VALUE *argv, VALUE obj)
{
    return rb_fiber_s_schedule_kw(argc, argv, rb_keyword_given_p());
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-scheduler" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          scheduler &rarr; obj or nil
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns the <a href="Fiber.html"><code>Fiber</code></a> scheduler, that was last set for the current thread with <a href="Fiber.html#method-c-set_scheduler"><code>Fiber.set_scheduler</code></a>. Returns <code>nil</code> if no scheduler is set (which is the default), and non-blocking fibers’ behavior is the same as blocking. (see “Non-blocking fibers” section in class docs for details about the scheduler concept).</p>

                              <div class="method-source-code" id="scheduler-source">
            <pre>static VALUE
rb_fiber_s_scheduler(VALUE klass)
{
    return rb_fiber_scheduler_get();
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-set_scheduler" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          set_scheduler(scheduler) &rarr; scheduler
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets the <a href="Fiber.html"><code>Fiber</code></a> scheduler for the current thread. If the scheduler is set, non-blocking fibers (created by <a href="Fiber.html#method-c-new"><code>Fiber.new</code></a> with <code>blocking: false</code>, or by <a href="Fiber.html#method-c-schedule"><code>Fiber.schedule</code></a>) call that scheduler’s hook methods on potentially blocking operations, and the current thread will call scheduler’s <code>close</code> method on finalization (allowing the scheduler to properly manage all non-finished fibers).</p>

<p><code>scheduler</code> can be an object of any class corresponding to <a href="Fiber/Scheduler.html"><code>Fiber::Scheduler</code></a>. Its implementation is up to the user.</p>

<p>See also the “Non-blocking fibers” section in class docs.</p>

                              <div class="method-source-code" id="set_scheduler-source">
            <pre>static VALUE
rb_fiber_set_scheduler(VALUE klass, VALUE scheduler)
{
    return rb_fiber_scheduler_set(scheduler);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-yield" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          yield(args, ...) &rarr; obj
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Yields control back to the context that resumed the fiber, passing along any arguments that were passed to it. The fiber will resume processing at this point when <a href="Fiber.html#method-i-resume"><code>resume</code></a> is called next. Any arguments passed to the next <a href="Fiber.html#method-i-resume"><code>resume</code></a> will be the value that this <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a> expression evaluates to.</p>

                              <div class="method-source-code" id="yield-source">
            <pre>static VALUE
rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass)
{
    return rb_fiber_yield_kw(argc, argv, rb_keyword_given_p());
}</pre>
                              </div>
                            </div>


                          </div>

                          </section>

                <section id="public-instance-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Instance Methods</h3>
                </header>

                  <div id="method-i-alive-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          alive? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns true if the fiber can still be resumed (or transferred to). After finishing execution of the fiber block this method will always return <code>false</code>.</p>

                              <div class="method-source-code" id="alive-3F-source">
            <pre>VALUE
rb_fiber_alive_p(VALUE fiber_value)
{
    return RBOOL(!FIBER_TERMINATED_P(fiber_ptr(fiber_value)));
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-backtrace" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace &rarr; array
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace(start) &rarr; array
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace(start, count) &rarr; array
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace(start..end) &rarr; array
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Returns the current execution stack of the fiber. <code>start</code>, <code>count</code> and <code>end</code> allow to select only parts of the backtrace.</p>

<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">level3</span>
  <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">yield</span>
<span class="ruby-keyword">end</span>

<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">level2</span>
  <span class="ruby-identifier">level3</span>
<span class="ruby-keyword">end</span>

<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">level1</span>
  <span class="ruby-identifier">level2</span>
<span class="ruby-keyword">end</span>

<span class="ruby-identifier">f</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> { <span class="ruby-identifier">level1</span> }

<span class="ruby-comment"># It is empty before the fiber started</span>
<span class="ruby-identifier">f</span>.<span class="ruby-identifier">backtrace</span>
<span class="ruby-comment">#=&gt; []</span>

<span class="ruby-identifier">f</span>.<span class="ruby-identifier">resume</span>

<span class="ruby-identifier">f</span>.<span class="ruby-identifier">backtrace</span>
<span class="ruby-comment">#=&gt; [&quot;test.rb:2:in `yield&#39;&quot;, &quot;test.rb:2:in `level3&#39;&quot;, &quot;test.rb:6:in `level2&#39;&quot;, &quot;test.rb:10:in `level1&#39;&quot;, &quot;test.rb:13:in `block in &lt;main&gt;&#39;&quot;]</span>
<span class="ruby-identifier">p</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">backtrace</span>(<span class="ruby-value">1</span>) <span class="ruby-comment"># start from the item 1</span>
<span class="ruby-comment">#=&gt; [&quot;test.rb:2:in `level3&#39;&quot;, &quot;test.rb:6:in `level2&#39;&quot;, &quot;test.rb:10:in `level1&#39;&quot;, &quot;test.rb:13:in `block in &lt;main&gt;&#39;&quot;]</span>
<span class="ruby-identifier">p</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">backtrace</span>(<span class="ruby-value">2</span>, <span class="ruby-value">2</span>) <span class="ruby-comment"># start from item 2, take 2</span>
<span class="ruby-comment">#=&gt; [&quot;test.rb:6:in `level2&#39;&quot;, &quot;test.rb:10:in `level1&#39;&quot;]</span>
<span class="ruby-identifier">p</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">backtrace</span>(<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">3</span>) <span class="ruby-comment"># take items from 1 to 3</span>
<span class="ruby-comment">#=&gt; [&quot;test.rb:2:in `level3&#39;&quot;, &quot;test.rb:6:in `level2&#39;&quot;, &quot;test.rb:10:in `level1&#39;&quot;]</span>

<span class="ruby-identifier">f</span>.<span class="ruby-identifier">resume</span>

<span class="ruby-comment"># It is nil after the fiber is finished</span>
<span class="ruby-identifier">f</span>.<span class="ruby-identifier">backtrace</span>
<span class="ruby-comment">#=&gt; nil</span>
</pre>

                              <div class="method-source-code" id="backtrace-source">
            <pre>static VALUE
rb_fiber_backtrace(int argc, VALUE *argv, VALUE fiber)
{
    return rb_vm_backtrace(argc, argv, &amp;fiber_ptr(fiber)-&gt;cont.saved_ec);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-backtrace_locations" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace_locations &rarr; array
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace_locations(start) &rarr; array
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace_locations(start, count) &rarr; array
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          backtrace_locations(start..end) &rarr; array
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Like <a href="Fiber.html#method-i-backtrace"><code>backtrace</code></a>, but returns each line of the execution stack as a <a href="Thread/Backtrace/Location.html"><code>Thread::Backtrace::Location</code></a>. Accepts the same arguments as <a href="Fiber.html#method-i-backtrace"><code>backtrace</code></a>.</p>

<pre class="ruby"><span class="ruby-identifier">f</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> { <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">yield</span> }
<span class="ruby-identifier">f</span>.<span class="ruby-identifier">resume</span>
<span class="ruby-identifier">loc</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">backtrace_locations</span>.<span class="ruby-identifier">first</span>
<span class="ruby-identifier">loc</span>.<span class="ruby-identifier">label</span>  <span class="ruby-comment">#=&gt; &quot;yield&quot;</span>
<span class="ruby-identifier">loc</span>.<span class="ruby-identifier">path</span>   <span class="ruby-comment">#=&gt; &quot;test.rb&quot;</span>
<span class="ruby-identifier">loc</span>.<span class="ruby-identifier">lineno</span> <span class="ruby-comment">#=&gt; 1</span>
</pre>

                              <div class="method-source-code" id="backtrace_locations-source">
            <pre>static VALUE
rb_fiber_backtrace_locations(int argc, VALUE *argv, VALUE fiber)
{
    return rb_vm_backtrace_locations(argc, argv, &amp;fiber_ptr(fiber)-&gt;cont.saved_ec);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-blocking-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          blocking? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns <code>true</code> if <code>fiber</code> is blocking and <code>false</code> otherwise. <a href="Fiber.html"><code>Fiber</code></a> is non-blocking if it was created via passing <code>blocking: false</code> to <a href="Fiber.html#method-c-new"><code>Fiber.new</code></a>, or via <a href="Fiber.html#method-c-schedule"><code>Fiber.schedule</code></a>.</p>

<p>Note that, even if the method returns <code>false</code>, the fiber behaves differently only if <a href="Fiber.html#method-c-scheduler"><code>Fiber.scheduler</code></a> is set in the current thread.</p>

<p>See the “Non-blocking fibers” section in class docs for details.</p>

                              <div class="method-source-code" id="blocking-3F-source">
            <pre>VALUE
rb_fiber_blocking_p(VALUE fiber)
{
    return RBOOL(fiber_ptr(fiber)-&gt;blocking);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-inspect" class="method-detail method-alias">
                            <div class="method-heading">
                              <span class="method-name">inspect</span><span
                                class="method-args">()</span>
                            </div>

                            <div class="method-description">
                              

                            </div>


                            <div class="aliases">
                              Alias for: <a href="Fiber.html#method-i-to_s">to_s</a>
                            </div>
                          </div>

                  <div id="method-i-kill" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          kill &rarr; nil
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Terminates <code>fiber</code> by raising an uncatchable exception, returning the terminated <a href="Fiber.html"><code>Fiber</code></a>.</p>

<p>If the fiber has not been started, transition directly to the terminated state.</p>

<p>If the fiber is already terminated, does nothing.</p>

                              <div class="method-source-code" id="kill-source">
            <pre>static VALUE
rb_fiber_m_kill(VALUE self)
{
    rb_fiber_t *fiber = fiber_ptr(self);

    if (fiber-&gt;killed) return Qfalse;
    fiber-&gt;killed = 1;

    if (fiber-&gt;status == FIBER_CREATED) {
        fiber-&gt;status = FIBER_TERMINATED;
    }
    else if (fiber-&gt;status != FIBER_TERMINATED) {
        if (fiber_current() == fiber) {
            fiber_check_killed(fiber);
        } else {
            fiber_raise(fiber_ptr(self), Qnil);
        }
    }

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-raise" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          raise                                 &rarr; obj
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          raise(string)                         &rarr; obj
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          raise(exception [, string [, array]]) &rarr; obj
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Raises an exception in the fiber at the point at which the last <code>Fiber.yield</code> was called. If the fiber has not been started or has already run to completion, raises <code>FiberError</code>. If the fiber is yielding, it is resumed. If it is transferring, it is transferred into. But if it is resuming, raises <code>FiberError</code>.</p>

<p>With no arguments, raises a <code>RuntimeError</code>. With a single <code>String</code> argument, raises a <code>RuntimeError</code> with the string as a message.  Otherwise, the first parameter should be the name of an <code>Exception</code> class (or an object that returns an <code>Exception</code> object when sent an <code>exception</code> message). The optional second parameter sets the message associated with the exception, and the third parameter is an array of callback information. Exceptions are caught by the <code>rescue</code> clause of <code>begin...end</code> blocks.</p>

                              <div class="method-source-code" id="raise-source">
            <pre>static VALUE
rb_fiber_m_raise(int argc, VALUE *argv, VALUE self)
{
    return rb_fiber_raise(self, argc, argv);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-resume" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          resume(args, ...) &rarr; obj
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Resumes the fiber from the point at which the last <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a> was called, or starts running it if it is the first call to <a href="Fiber.html#method-i-resume"><code>resume</code></a>. Arguments passed to resume will be the value of the <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a> expression or will be passed as block parameters to the fiber’s block if this is the first <a href="Fiber.html#method-i-resume"><code>resume</code></a>.</p>

<p>Alternatively, when resume is called it evaluates to the arguments passed to the next <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a> statement inside the fiber’s block or to the block value if it runs to completion without any <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a></p>

                              <div class="method-source-code" id="resume-source">
            <pre>static VALUE
rb_fiber_m_resume(int argc, VALUE *argv, VALUE fiber)
{
    return rb_fiber_resume_kw(fiber, argc, argv, rb_keyword_given_p());
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-storage" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          storage &rarr; hash (dup)
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns a copy of the storage hash for the fiber. The method can only be called on the <a href="Fiber.html#method-c-current"><code>Fiber.current</code></a>.</p>

                              <div class="method-source-code" id="storage-source">
            <pre>static VALUE
rb_fiber_storage_get(VALUE self)
{
    storage_access_must_be_from_same_fiber(self);

    VALUE storage = fiber_storage_get(fiber_ptr(self), FALSE);

    if (storage == Qnil) {
        return Qnil;
    }
    else {
        return rb_obj_dup(storage);
    }
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-storage-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          storage = hash
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets the storage hash for the fiber. This feature is experimental and may change in the future. The method can only be called on the <a href="Fiber.html#method-c-current"><code>Fiber.current</code></a>.</p>

<p>You should be careful about using this method as you may inadvertently clear important fiber-storage state. You should mostly prefer to assign specific keys in the storage using <a href="Fiber.html#method-c-5B-5D-3D"><code>Fiber::[]=</code></a>.</p>

<p>You can also use <code>Fiber.new(storage: nil)</code> to create a fiber with an empty storage.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-keyword">while</span> <span class="ruby-identifier">request</span> = <span class="ruby-identifier">request_queue</span>.<span class="ruby-identifier">pop</span>
  <span class="ruby-comment"># Reset the per-request state:</span>
  <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">current</span>.<span class="ruby-identifier">storage</span> = <span class="ruby-keyword">nil</span>
  <span class="ruby-identifier">handle_request</span>(<span class="ruby-identifier">request</span>)
<span class="ruby-keyword">end</span>
</pre>

                              <div class="method-source-code" id="storage-3D-source">
            <pre>static VALUE
rb_fiber_storage_set(VALUE self, VALUE value)
{
    if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL)) {
        rb_category_warn(RB_WARN_CATEGORY_EXPERIMENTAL,
          &quot;Fiber#storage= is experimental and may be removed in the future!&quot;);
    }

    storage_access_must_be_from_same_fiber(self);
    fiber_storage_validate(value);

    fiber_ptr(self)-&gt;cont.saved_ec.storage = rb_obj_dup(value);
    return value;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-to_s" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">to_s</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="to_s-source">
            <pre>static VALUE
fiber_to_s(VALUE fiber_value)
{
    const rb_fiber_t *fiber = fiber_ptr(fiber_value);
    const rb_proc_t *proc;
    char status_info[0x20];

    if (fiber-&gt;resuming_fiber) {
        snprintf(status_info, 0x20, &quot; (%s by resuming)&quot;, fiber_status_name(fiber-&gt;status));
    }
    else {
        snprintf(status_info, 0x20, &quot; (%s)&quot;, fiber_status_name(fiber-&gt;status));
    }

    if (!rb_obj_is_proc(fiber-&gt;first_proc)) {
        VALUE str = rb_any_to_s(fiber_value);
        strlcat(status_info, &quot;&gt;&quot;, sizeof(status_info));
        rb_str_set_len(str, RSTRING_LEN(str)-1);
        rb_str_cat_cstr(str, status_info);
        return str;
    }
    GetProcPtr(fiber-&gt;first_proc, proc);
    return rb_block_to_s(fiber_value, &amp;proc-&gt;block, status_info);
}</pre>
                              </div>
                            </div>

                            <div class="aliases">
                              Also aliased as: <a href="Fiber.html#method-i-inspect">inspect</a>
                            </div>

                          </div>

                  <div id="method-i-transfer" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          transfer(args, ...) &rarr; obj
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Transfer control to another fiber, resuming it from where it last stopped or starting it if it was not resumed before. The calling fiber will be suspended much like in a call to <a href="Fiber.html#method-c-yield"><code>Fiber.yield</code></a>.</p>

<p>The fiber which receives the transfer call treats it much like a resume call. Arguments passed to transfer are treated like those passed to resume.</p>

<p>The two style of control passing to and from fiber (one is <a href="Fiber.html#method-i-resume"><code>resume</code></a> and <a href="Fiber.html#method-c-yield"><code>Fiber::yield</code></a>, another is <a href="Fiber.html#method-i-transfer"><code>transfer</code></a> to and from fiber) can’t be freely mixed.</p>
<ul><li>
<p>If the Fiber’s lifecycle had started with transfer, it will never be able to yield or be resumed control passing, only finish or transfer back. (It still can resume other fibers that are allowed to be resumed.)</p>
</li><li>
<p>If the Fiber’s lifecycle had started with resume, it can yield or transfer to another <a href="Fiber.html"><code>Fiber</code></a>, but can receive control back only the way compatible with the way it was given away: if it had transferred, it only can be transferred back, and if it had yielded, it only can be resumed back. After that, it again can transfer or yield.</p>
</li></ul>

<p>If those rules are broken <a href="FiberError.html"><code>FiberError</code></a> is raised.</p>

<p>For an individual <a href="Fiber.html"><code>Fiber</code></a> design, yield/resume is easier to use (the <a href="Fiber.html"><code>Fiber</code></a> just gives away control, it doesn’t need to think about who the control is given to), while transfer is more flexible for complex cases, allowing to build arbitrary graphs of Fibers dependent on each other.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">manager</span> = <span class="ruby-keyword">nil</span> <span class="ruby-comment"># For local var to be visible inside worker block</span>

<span class="ruby-comment"># This fiber would be started with transfer</span>
<span class="ruby-comment"># It can&#39;t yield, and can&#39;t be resumed</span>
<span class="ruby-identifier">worker</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">work</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Worker: starts&quot;</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;Worker: Performed #{work.inspect}, transferring back&quot;</span>
  <span class="ruby-comment"># Fiber.yield     # this would raise FiberError: attempt to yield on a not resumed fiber</span>
  <span class="ruby-comment"># manager.resume  # this would raise FiberError: attempt to resume a resumed fiber (double resume)</span>
  <span class="ruby-identifier">manager</span>.<span class="ruby-identifier">transfer</span>(<span class="ruby-identifier">work</span>.<span class="ruby-identifier">capitalize</span>)
}

<span class="ruby-comment"># This fiber would be started with resume</span>
<span class="ruby-comment"># It can yield or transfer, and can be transferred</span>
<span class="ruby-comment"># back or resumed</span>
<span class="ruby-identifier">manager</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span> {
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Manager: starts&quot;</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Manager: transferring &#39;something&#39; to worker&quot;</span>
  <span class="ruby-identifier">result</span> = <span class="ruby-identifier">worker</span>.<span class="ruby-identifier">transfer</span>(<span class="ruby-string">&#39;something&#39;</span>)
  <span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;Manager: worker returned #{result.inspect}&quot;</span>
  <span class="ruby-comment"># worker.resume    # this would raise FiberError: attempt to resume a transferring fiber</span>
  <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">yield</span>        <span class="ruby-comment"># this is OK, the fiber transferred from and to, now it can yield</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Manager: finished&quot;</span>
}

<span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Starting the manager&quot;</span>
<span class="ruby-identifier">manager</span>.<span class="ruby-identifier">resume</span>
<span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;Resuming the manager&quot;</span>
<span class="ruby-comment"># manager.transfer  # this would raise FiberError: attempt to transfer to a yielding fiber</span>
<span class="ruby-identifier">manager</span>.<span class="ruby-identifier">resume</span>
</pre>

<p><em>produces</em></p>

<pre>Starting the manager
Manager: starts
Manager: transferring &#39;something&#39; to worker
Worker: starts
Worker: Performed &quot;something&quot;, transferring back
Manager: worker returned &quot;Something&quot;
Resuming the manager
Manager: finished</pre>

                              <div class="method-source-code" id="transfer-source">
            <pre>static VALUE
rb_fiber_m_transfer(int argc, VALUE *argv, VALUE self)
{
    return rb_fiber_transfer_kw(self, argc, argv, rb_keyword_given_p());
}</pre>
                              </div>
                            </div>


                          </div>

                          </section>

              </section>
              </main>



            </div>  <!--  class='wrapper hdiv' -->


<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a></p>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.4.0.</p>
<p>Based on <a href="https://github.com/ged/darkfish/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.</p>

  
    <p><p><a href="https://ruby-doc.org">Ruby-doc.org</a> is provided by <a href="https://jamesbritt.com">James Britt</a> and <a href="https://neurogami.com">Neurogami</a>.</p><p><a href="https://jamesbritt.bandcamp.com/">Maximum R+D</a>.  </p>
</p>
  
  </footer>

<script type="text/javascript">


  let ads  = $("#carbonads-container").children().detach();


  function swapMode() {
    var cookieName = 'darkmode';
    var cssDarkmode = Cookies.get(cookieName);
    console.log("***** swapMode! " + cssDarkmode + " *****");


    if (cssDarkmode == "true") {
      console.log("We have dark mode, set the css to light ...");
      $('#rdoccss').attr("href", defaultModeCssHref);
      $('#cssSelect').text("Dark mode");
      cssDarkmode = "false";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    } else {
      console.log("We not have dark mode, set the css to dark ...");
      $('#rdoccss').attr("href", darkModeCsseHref);
      $('#cssSelect').text("Light mode");
      cssDarkmode = "true";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    }

    console.log("  --------------- ");
  }


const vueCssApp = new Vue({
el: '#menubar',
data: {
isDark: false
},
methods: {
toggleClass: function(event){
this.isDark = !this.isDark;
}
}
})

const vueApp = new Vue({
el: '#vapp',
data: { 
isOpen: true
},

mounted() {
this.handleResize();
this.manage_mob_classes();
window.addEventListener('resize', this.handleResize)
//this.isOpen !=  (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
created() {
//manage_mob_classes();
},

methods : {
isMobile() {
  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},

  handleResize() {
    if (!this.isMobile()) {
      this.isOpen = window.innerWidth > 800;
    }
  },

  manage_mob_classes() {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
      $("nav").addClass("mob_nav");
      $("main").addClass("mob_main");
      $("#extraz").addClass("mob_extraz");
      $("#carbonads-container").addClass("mob_carbonads-container");
      this.isOpen  = false;
    } else {
      $("nav").removeClass("mob_nav") 
        $("main").removeClass("mob_main");
      $("#extraz").removeClass("mob_extraz");
      $("#carbonads-container").removeClass("mob_carbonads-container");
      this.isOpen  = true;
    }
  },

  toggleNav() {
    this.isOpen =! this.isOpen ;
    // alert("Toggle nav!");
    console.log("toggleNav() click: " + this.isOpen );
  }
}
})

$("#carbonads-container").append(ads);


$(function() {

    var darkmode = Cookies.get("darkmode");
    console.log("Document ready: " + darkmode);

    if ( darkmode  == "true" ) {
      $('#cssSelect').text("Light mode");
    } else {
      $('#cssSelect').text("Dark mode");
     }

    $('body').css('display','block');
    });

</script>

    
  </body> 
</html>

